package com.neusoft.databus.core.converter;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.google.common.collect.Maps;
import com.neusoft.bizcore.web.dto.AbstractConverter;
import com.neusoft.bizcore.web.utils.id.BaseIdGenerator;
import com.neusoft.databus.common.dto.ResourceDTO;
import com.neusoft.databus.common.enums.DictionaryType;
import com.neusoft.databus.common.model.Gateway;
import com.neusoft.databus.common.model.MetricGroup;
import com.neusoft.databus.common.model.Resource;
import com.neusoft.databus.core.constant.DatabusCoreConstant;
import com.neusoft.databus.core.repository.GatewayRepository;
import com.neusoft.databus.core.repository.MetricGroupRepository;
import com.neusoft.databus.core.repository.ResourceRepository;
import com.neusoft.databus.core.service.DictionaryService;
import com.neusoft.databus.core.vo.ResourcePortVO;

/**
 * 资源转换器
 *
 * @author sunchf
 * @date 2018年12月24日 上午9:44:01
 */
@Component
public class ResourceConverter extends AbstractConverter<Resource, ResourceDTO> {

    @Autowired
    private ResourceRepository resourceRepository;
    @Autowired
    private MetricGroupConverter metricGroupConverter;
    @Autowired
    private MetricGroupRepository metricGroupRepository;
    @Autowired
    private GatewayRepository gatewayRepository;
    @Autowired
    private GatewayConverter gatewayConverter;
    @Autowired
    private BaseIdGenerator resourceCodeGenerator;
    @Autowired
    private DictionaryService dictionaryService;

    private final Map<String, String> types = Maps.newHashMap();

    /**
     * 编码：不允许更新 <br>
     * 指标组：单独API维护 <br>
     * 禁用状态：单独API维护
     */
    @Override
    public Resource toModel(final ResourceDTO dto) {
        Resource model;
        if (dto.isNew()) {
            model = new Resource();
            if (!StringUtils.isEmpty(dto.getCode())) {
                model.setCode(dto.getCode().trim());
            } else {
                model.setCode(this.resourceCodeGenerator.generateCode());
            }

        } else {
            model = this.resourceRepository.getOne(dto.getId());
            model.setCode(dto.getCode().trim());
        }
        // 网关可以为空
        final String gatewayCode = dto.getGatewayCode();
        if (!StringUtils.isEmpty(gatewayCode)) {
            final Gateway gateway = this.gatewayRepository.findByCode(gatewayCode);
            if (null != gateway) {
                model.setGateway(gateway);
            }
        } else {
            model.setGateway(null);
        }
        model.setName(dto.getName());
        model.setType(dto.getType());
        model.setConfig(dto.getConfig());
        model.setAssociate(dto.getAssociate());
        model.setComment(dto.getComment());
        model.setExecutionCycle(dto.getExecutionCycle());
        return model;
    }

    @Override
    public ResourceDTO toDTO(final Resource model, final boolean forListView) {
        final ResourceDTO dto = new ResourceDTO();
        dto.setId(model.getId());
        dto.setCode(model.getCode());
        dto.setName(model.getName());
        dto.setDisabled(model.isDisabled());
        dto.setConfig(model.getConfig());
        dto.setCreateTime(model.getCreateTime());
        dto.setUpdateTime(model.getUpdateTime());
        dto.setType(model.getType());
        dto.setAssociate(model.getAssociate());
        if (null != model.getGateway()) {
            dto.setGatewayCode(model.getGateway().getCode());
            dto.setGateway(this.gatewayConverter.toDTO(model.getGateway()));
        }
        final List<MetricGroup> metricGroups = model.getMetricGroups();
        dto.setMetricGroupSize(metricGroups.size());
        dto.getMetricGroups().addAll(
                metricGroups.stream().map(g -> this.metricGroupConverter.toDTO(g, forListView))
                        .collect(Collectors.toList()));
        dto.setComment(model.getComment());
        dto.setExecutionCycle(model.getExecutionCycle());
        return dto;
    }

    public ResourceDTO toSelfDTO(final Resource model) {
        final ResourceDTO dto = new ResourceDTO();
        dto.setId(model.getId());
        dto.setCode(model.getCode());
        dto.setName(model.getName());
        dto.setDisabled(model.isDisabled());
        dto.setConfig(model.getConfig());
        dto.setCreateTime(model.getCreateTime());
        dto.setUpdateTime(model.getUpdateTime());
        dto.setType(model.getType());
        dto.setAssociate(model.getAssociate());
        dto.setComment(model.getComment());
        dto.setExecutionCycle(model.getExecutionCycle());
        return dto;
    }

    public Resource toModel(final ResourcePortVO portVO) {
        final Resource model = new Resource();
        //        if (!StringUtils.isEmpty(portVO.getCode())) {
        //            model.setCode(portVO.getCode().trim());
        //        } else {
        model.setCode(this.resourceCodeGenerator.generateCode());
        //        }
        // 网关可以为空
        final String gatewayCode = portVO.getGatewayCode();
        if (StringUtils.isNotBlank(gatewayCode)) {
            final Gateway gateway = this.gatewayRepository.findByCode(gatewayCode);
            if (null != gateway) {
                model.setGateway(gateway);
            }
        } else {
            model.setGateway(null);
        }
        // 指标组可以为空，也可以为多个用，分割
        if (StringUtils.isNotBlank(portVO.getMetricGroupCode())) {
            final List<String> metricGroupCodes = Arrays.asList(portVO.getMetricGroupCode().split(","));
            metricGroupCodes.forEach(c -> {
                final MetricGroup group = this.metricGroupRepository.findByCode(c);
                if (null != group) {
                    model.getMetricGroups().add(group);
                }
            });
        }
        model.setName(portVO.getName());
        model.setType(portVO.getType().split(DatabusCoreConstant.DICTIONARY_SPLITOR)[0]);
        if (StringUtils.isNotBlank(portVO.getConfig())) {
            model.setConfig(portVO.getConfig());
        }
        model.setAssociate(portVO.getAssociate());
        model.setExecutionCycle(60L);
        return model;
    }

    public ResourcePortVO toVO(final Resource model) {
        final ResourcePortVO portVO = new ResourcePortVO();
        if (null != model.getGateway()) {
            portVO.setGatewayName(model.getGateway().getName());
        }
        if (model.getMetricGroups().size() > 0) {
            final StringBuffer mgName = new StringBuffer();
            model.getMetricGroups().forEach(mg -> {
                mgName.append(mg.getName()).append(",");
            });
            portVO.setMetricGroupName(mgName.substring(0, mgName.length() - 1));
        }
        portVO.setName(model.getName());
        portVO.setType(this.getType(model.getType()));
        return portVO;
    }

    private String getType(final String type) {
        if (this.types.isEmpty()) {
            this.dictionaryService.findByDictionaryTypeAndParentIsNotNull(DictionaryType.resource).forEach(d -> {
                this.types.put(d.getCode(), d.getText());
            });
        }
        return this.types.get(type);
    }
}
